/*
 * @Author: ZephyrGao
 * @Date: 2024-02-19 09:54:11
 * @Description: bem命令约定工具类
 * 
 * antd:  namespace（antdesign所有样式都是antd开头）
   -   :  block（代表块级区域） bl
   __  :  element（连接元素内容） el
   --  :  modifier（修饰内容，例如 按钮大小, 按钮颜色红、黄、蓝等）Mod
 * Copyright (c) 2024 by ZephyrGao, All Rights Reserved. 
 */

import { lessPrefixCls } from "@/config/designConfig";

type Mod = string | { [key: string]: any }
type Mods = Mod | Mod[]

/**
 * @param el 
 * @param mods 
 * 
 * @description 按照 bem 约定构建 class
 * 
 * genBem('button') // ''
 * genBem('button', 'large') // 'button--large'
 * genBem('button', ['large', 'primary']) // 'button--large button--primary'
 * genBem('button', { large: true, primary: true }) // 'button--large button--primary'
 * 
*/
function genBem(el: string, mods?: Mods): string {
  if (!mods) return ''
  if (typeof mods === 'string') return ` ${el}--${mods}`
  if (Array.isArray(mods)) return mods.reduce((ret, item) => ret + genBem(el, item), '')
  return Object.entries(mods).reduce((ret, [key, value]) => ret + (value ? ` ${el}--${key}` : ''), '')
}

/// 

/**
 * @param  name
 * 
 * @description 按照 bem 约定构建 class
 * 先创建const fn = buildBEM('blockName') fn是一个高阶函数 blockName是一个跨
 * fn()  // blockName
 * fn('primary') // "button__primary"  
 * fn(undefined, 'active'); // "button--active"  
 * fn('primary', 'active'); // "button__primary--active"  
 * fn('primary', [{ active: true }, { disabled: false }]) "button__primary--active" 
 * fn('primary', { active: true, disabled: false });
*/
export function buildBEM(blockName: string) {

  return (el?: Mods, mods?: Mods): Mods => {
    if (el && typeof el !== 'string') {
      mods = el;
      el = '';
    }
    el = el ? `${blockName}__${el}` : blockName;
    return `${el}${genBem(el, mods)}`;
  };
}

// const [bem] = createBEM('button')
export function createBEM(name: string) {
  return [buildBEM(`${lessPrefixCls}-${name}`)];
}

export function createNamespace(name: string) {
  const prefixedName = `${lessPrefixCls}-${name}`;
  return [prefixedName, buildBEM(prefixedName)] as const;
}